#include <arch/types.h>
#include <arch/CPU.h>

CPU CPU0;
CPU *CPUs[256] = { &CPU0 };

void CPU::Halt() {
	asm ("	CLI\n\
		HLT");
}

dword CPU::DisableInterrupts() {
	dword ret;
	asm volatile ("	PUSHFL\n\
			POPL	%0"
			:"=r" (ret));
	asm volatile ("	CLI");
	return ret;	
}

dword CPU::EnableInterrupts() {
	dword ret;
	asm volatile ("	PUSHFL\n\
			POPL	%0"
			:"=r" (ret));
	asm volatile ("	STI");
	return ret;
}

void CPU::RestoreInterrupts(dword oldFlags) {
	if (oldFlags & EFLAGS_IF) {
		asm volatile ("STI");
	} else {
		asm volatile ("CLI");
	}
}

dword CPU::ReadCR0() {
	dword ret;
	asm ("	MOVL	%%CR0, %0"
		:"=r" (ret));
	return ret;
}

dword CPU::ReadCR1() {
	dword ret;
	asm ("	MOVL	%%CR1, %0"
		:"=r" (ret));
	return ret;
}

dword CPU::ReadCR2() {
	dword ret;
	asm ("	MOVL	%%CR2, %0"
		:"=r" (ret));
	return ret;
}

dword CPU::ReadCR3() {
	dword ret;
	asm ("	MOVL	%%CR3, %0"
		:"=r" (ret));
	return ret;
}

dword CPU::ReadCR4() {
	dword ret;
	asm ("	MOVL	%%CR4, %0"
		:"=r" (ret));
	return ret;
}

void CPU::WriteCR0(dword value) {
	asm ("	MOVL	%0, %%CR0"
		:
		:"r" (value));
}

void CPU::WriteCR1(dword value) {
	asm ("	MOVL	%0, %%CR1"
		:
		:"r" (value));
}

void CPU::WriteCR2(dword value) {
	asm ("	MOVL	%0, %%CR2"
		:
		:"r" (value));
}

void CPU::WriteCR3(dword value) {
	asm ("	MOVL	%0, %%CR3"
		:
		:"r" (value));
}

void CPU::WriteCR4(dword value) {
	asm ("	MOVL	%0, %%CR4"
		:
		:"r" (value));
}
